package com.lyf.scm.admin.domain.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.github.pagehelper.PageInfo;
import com.lyf.scm.admin.api.dto.*;
import com.lyf.scm.admin.domain.excel.dto.RequirementDTO;
import com.lyf.scm.admin.domain.remote.allocationservice.facade.*;
import com.lyf.scm.admin.domain.remote.basedata.dto.StoreDTO;
import com.lyf.scm.admin.domain.remote.basedata.facade.BaseDataFacade;
import com.lyf.scm.admin.domain.remote.item.dto.CategoryBaseInfoDTO;
import com.lyf.scm.admin.domain.remote.item.dto.SkuInfoDTO;
import com.lyf.scm.admin.domain.remote.item.facade.ItemCoreFacade;
import com.lyf.scm.admin.domain.remote.purchase.dto.PlanPoQueryDTO;
import com.lyf.scm.admin.domain.remote.stock.facade.StockFacade;
import com.lyf.scm.admin.domain.service.RequirementPlanService;
import com.lyf.scm.admin.domain.util.OtherTargetHandleUtil;
import com.lyf.scm.admin.domain.util.RequirementDataListener;
import com.lyf.scm.common.constants.CommonConstants;
import com.lyf.scm.common.enums.*;
import com.lyf.scm.common.model.ExcelExportDTO;
import com.lyf.scm.common.model.ExcelExportDataDTO;
import com.lyf.scm.common.model.SalesPlanSelectDTO;
import com.lyf.scm.common.util.AdvancedSearchUtil;
import com.lyf.scm.common.util.ExcelExportUtil;
import com.lyf.scm.common.util.date.MyDateUtil;
import com.lyf.scm.common.util.style.GeneralCellWriteHandler;
import com.rome.arch.core.exception.RomeException;
import com.rome.user.DTO.ApplicationUserInfoDTO;
import com.rome.user.common.utils.UserContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static com.lyf.scm.common.enums.RequirementPlanEnum.*;
import static com.lyf.scm.common.util.AdvancedSearchUtil.getExcelDateTitle;
import static com.lyf.scm.common.util.BatchHandlerUtil.splitTo;

/**
 * 需求计划
 *
 * @author wangchlei
 * @date 2020/10/26
 */
@Slf4j
@Service
public class RequirementPlanServiceImpl implements RequirementPlanService {
    @Resource
    private RequirementPlanFacade requirementPlanFacade;
    @Resource
    private ItemCoreFacade itemCoreFacade;
    @Resource
    private BaseDataFacade baseDataFacade;
    @Resource
    private StockFacade stockFacade;
    @Resource
    private SalesPlanEsFacade salesPlanEsFacade;
    @Resource
    private OtherTargetGeneralHandlerFacade otherTargetGeneralHandlerFacade;
    @Resource
    private SalesPlanEsLazyLoadingFacade salesPlanEsLazyLoadingFacade;
    @Resource
    private OperationLogRecordFacade logRecordFacade;
    @Resource
    @Lazy
    private RequirementPlanServiceImpl requirementPlanServiceImpl;
    @Value("${filePath}")
    private String filePath;

    /**
     * 获取列表数据
     * <p>
     * 渠道，计划类型，区域（省市区），仓库，品类（不分组），sku
     *
     * @param requirementPlanDTO
     * @return {@link PageInfo<RequirementPlanInfoDTO>}
     **/
    @Override
    public PlanResponseDTO<RequirementPlanInfoDTO> listWeekBySelective(RequirementPlanDTO requirementPlanDTO) {
        //获得最低级品类查询条件
        List<SalesPlanSelectDTO> areaSalesPlanSelectDTOs = baseDataFacade.getSubAreaCode(requirementPlanDTO.getAreaCodeList());
        //赋值品类搜索条件
        EsAggregationDTO esAggregationDTO = this.setSearchFields(requirementPlanDTO, requirementPlanDTO.getCategoryCodeList(), areaSalesPlanSelectDTOs);
        List<Map<String, Date>> weekDates = MyDateUtil.getWeekDates(requirementPlanDTO.getStartTime(), DataDisplayCycleEnum.WEEKLY_FOURTEEN.getValue());
        esAggregationDTO.setUnitType(requirementPlanDTO.getUnitType());
        esAggregationDTO.getEsQuery().setStartDate(DateUtil.format(weekDates.get(0).get("startTime"), DatePattern.NORM_DATE_PATTERN));
        esAggregationDTO.getEsQuery().setEndDate(DateUtil.format(weekDates.get(weekDates.size() - 1).get("endTime"), DatePattern.NORM_DATE_PATTERN));
        esAggregationDTO.setPageSize(requirementPlanDTO.getPageSize());
        esAggregationDTO.setPageNum(requirementPlanDTO.getPageNum());
        esAggregationDTO.setTableCode(TableCodeEnum.REQUIREMENT_PLAN.getCode());
        esAggregationDTO.setUserId(UserContext.getUserId());
        //获取起始十四周起始日期字符串集合
        List<String> dateList = new ArrayList<>();
        List<Date> dates = new ArrayList<>();
        for (Map<String, Date> item : weekDates) {
            dateList.add(DateUtil.format(item.get("startTime"), DatePattern.NORM_DATE_PATTERN));
            dates.add(item.get("startTime"));
        }
        esAggregationDTO.setDateList(dateList);
        PageInfo<EsReturnDTO> esReturnDTOS = salesPlanEsLazyLoadingFacade.pageQuery(esAggregationDTO);
        if (esReturnDTOS == null) {
            return null;
        }
        List<EsReturnDTO> result = esReturnDTOS.getList();
        if (CollectionUtils.isEmpty(result)) {
            return null;
        }
        PlanResponseDTO<RequirementPlanInfoDTO> planResponse = new PlanResponseDTO();
        planResponse.setPageNum(esReturnDTOS.getPageNum());
        planResponse.setHasNextPage(esReturnDTOS.isHasNextPage());
        List<RequirementPlanInfoDTO> pageList = new ArrayList<>();
        RequirementPlanInfoDTO requirementPlanInfoDTO;
        Map<String, List<BigDecimal>> targetmap;
        List<Integer> status = new ArrayList<>();
        long thisDayOfLong = DateUtil.beginOfWeek(new Date()).getTime();
        for (Date item : dates) {
            if (thisDayOfLong <= item.getTime()) {
                status.add(1);
            } else {
                status.add(0);
            }
        }
        //获取通用其它指标传输实体对象
        OtherTargetHandleUtil.handleResult(otherTargetGeneralHandlerFacade.getNecessaryOtherTargets(OtherTargetHandleUtil.getGeneralQueryDTO(esAggregationDTO, result, OtherTargetsEnum.REQUIREMENT_PALN)), result);
        for (EsReturnDTO esReturnDTO : result) {
            requirementPlanInfoDTO = this.getRequirementPlanInfoDTO();
            requirementPlanInfoDTO.setChannel(esReturnDTO.getChannelName());
            requirementPlanInfoDTO.setArea(esReturnDTO.getArea());
            requirementPlanInfoDTO.setPlanTypeName(esReturnDTO.getPlanTypeName());
            requirementPlanInfoDTO.setCategory(esReturnDTO.getCategory());
            requirementPlanInfoDTO.setSkuName(esReturnDTO.getSkuName());
            requirementPlanInfoDTO.setSkuCode(esReturnDTO.getSkuCode());
            requirementPlanInfoDTO.setWarehouseName(esReturnDTO.getDeliverName());
            requirementPlanInfoDTO.setWarehouseCode(esReturnDTO.getDeliverId());
            //指标
            targetmap = esReturnDTO.getTargetMap();
            requirementPlanInfoDTO.setSupChainConfirmQty(targetmap.get(EsSumColumnEnum.REQUIRE_CONFIRM_QTY.getColumn()));
            requirementPlanInfoDTO.setLastConfirmQty(targetmap.get(EsSumColumnEnum.LAST_REQUIRE_CONFIRM_QTY.getColumn()));
            requirementPlanInfoDTO.setSalesPlanQty(targetmap.get(EsSumColumnEnum.SALES_PLAN_QTY.getColumn()));
            requirementPlanInfoDTO.setForecastPlanQty(targetmap.get(EsSumColumnEnum.FORECAST_PLAN_QTY.getColumn()));
            requirementPlanInfoDTO.setSalePlanConfirmationQty(targetmap.get(EsSumColumnEnum.CONFIRM_L4.getColumn()));
            requirementPlanInfoDTO.setLastSalePlanConfirmQty(targetmap.get(EsSumColumnEnum.LAST_CONFIRM_L4.getColumn()));
            //其它指标
            requirementPlanInfoDTO.setStockSafety(targetmap.get(TiSsEnum.STOCK_SAFETY.getName()));
            requirementPlanInfoDTO.setTargetInventoryQty(targetmap.get(TiSsEnum.TARGET_INVENTORY.getName()));
            requirementPlanInfoDTO.setCoveredDays(targetmap.get(TiSsEnum.COVERED_DAYS.getName()));
            requirementPlanInfoDTO.setPurchasePlanQty(targetmap.get(PurchaseOrderTargetEnum.PURCHASE_PLAN_QUANTITY.getName()));
            requirementPlanInfoDTO.setPurchaseOrderQty(targetmap.get(PurchaseOrderTargetEnum.PURCHASE_ORDER_QUANTITY.getName()));
            requirementPlanInfoDTO.setNoFulfilPurchaseQty(targetmap.get(PurchaseOrderTargetEnum.UNFULFILLED_PURCHASE_QUANTITY.getName()));
            requirementPlanInfoDTO.setConfirmedPurchaseOrderQty(targetmap.get(PurchaseOrderTargetEnum.CONFIRMED_PURCHASE_ORDERS.getName()));
            requirementPlanInfoDTO.setReservePurchaseQty(targetmap.get(PurchaseOrderTargetEnum.APPOINTMENT_PURCHASE_QUANTITY.getName()));
            requirementPlanInfoDTO.setActualQty(targetmap.get(OtherTargetsEnum.ACTUAL_QTY.getName()));
            requirementPlanInfoDTO.setActualStorageQty(targetmap.get(OtherTargetsEnum.ACTUAL_STORAGE_QTY.getName()));
            requirementPlanInfoDTO.setActualSalesQty(targetmap.get(OtherTargetsEnum.ACTUAL_SALES.getName()));
            requirementPlanInfoDTO.setRealTimeInventory(targetmap.get(OtherTargetsEnum.REAL_TIME_STOCK.getName()));
            requirementPlanInfoDTO.setStatus(status);
            pageList.add(requirementPlanInfoDTO);
        }
        planResponse.setInfoList(pageList);
        planResponse.setDateList(MyDateUtil.processCyclesDate(weekDates, "M.dd"));
        return planResponse;
    }

    /**
     * 图表接口
     *
     * @param requirementPlanDTO
     * @return {@link EChartsDTO}
     **/
    @Override
    public EChartsDTO eChartsData(RequirementPlanDTO requirementPlanDTO) {
        List<SalesPlanSelectDTO> categorySalesPlanSelectDTOs = itemCoreFacade.getSubcategoryCode(requirementPlanDTO.getCategoryCodeList());
        List<SalesPlanSelectDTO> areaSalesPlanSelectDTOs = baseDataFacade.getSubAreaCode(requirementPlanDTO.getAreaCodeList());
        Date startTime = requirementPlanDTO.getStartTime();
        Date endTime = requirementPlanDTO.getEndTime();
        requirementPlanDTO.setStartTime(DateUtil.beginOfDay(DateUtil.beginOfWeek(startTime)));
        List<Map<String, Date>> weekDates = null;
        //按周
        if (null != endTime) {
            //结束时间设置为周日
            weekDates = MyDateUtil.getWeekDates(startTime, endTime);
        }
        if (null == endTime) {
            //默认14周
            weekDates = MyDateUtil.getWeekDates(startTime, DataDisplayCycleEnum.WEEKLY_FOURTEEN.getValue());
        }
        EsAggregationDTO esAggregationDTO = this.setEchartSearchFields(requirementPlanDTO, categorySalesPlanSelectDTOs, areaSalesPlanSelectDTOs);
        esAggregationDTO.getEsQuery().setStartDate(DateUtil.format(weekDates.get(0).get("startTime"), DatePattern.NORM_DATE_PATTERN));
        esAggregationDTO.getEsQuery().setEndDate(DateUtil.format(weekDates.get(weekDates.size() - 1).get("endTime"), DatePattern.NORM_DATE_PATTERN));
        //获取起始十四周起始日期字符串集合
        List<String> dateList = new ArrayList<>();
        List<Date> dates = new ArrayList<>();
        for (Map<String, Date> item : weekDates) {
            dateList.add(DateUtil.format(item.get("startTime"), DatePattern.NORM_DATE_PATTERN));
            dates.add(item.get("startTime"));
        }
        esAggregationDTO.setDateList(dateList);
        PageInfo<EsReturnDTO> pageList = salesPlanEsFacade.queryByGroup(esAggregationDTO);
        List<EsReturnDTO> list = pageList.getList();
        EChartsDTO eChartsDTO = new EChartsDTO();
        if (CollectionUtils.isEmpty(list)) {
            return eChartsDTO;
        }
        Map<String, List<BigDecimal>> value = new HashMap<>();
        Map<String, List<BigDecimal>> targetMap;
        for (EsReturnDTO esReturnDTO : list) {
            targetMap = esReturnDTO.getTargetMap();
            value.put(RequirementPlanEnum.PLAN_SALES.getType(), targetMap.get(EsSumColumnEnum.SALES_PLAN_QTY.getColumn()));
            value.put(RequirementPlanEnum.PREDICT_SALES.getType(), targetMap.get(EsSumColumnEnum.FORECAST_PLAN_QTY.getColumn()));
            value.put(RequirementPlanEnum.REQUIRE_CONFIRM_QTY.getType(), targetMap.get(EsSumColumnEnum.REQUIRE_CONFIRM_QTY.getColumn()));
            value.put(RequirementPlanEnum.CONFIRM_L4.getType(), targetMap.get(EsSumColumnEnum.CONFIRM_L4.getColumn()));
            value.put(RequirementPlanEnum.LAST_REQUIRE_CONFIRM_QTY.getType(), targetMap.get(EsSumColumnEnum.LAST_REQUIRE_CONFIRM_QTY.getColumn()));
            value.put(RequirementPlanEnum.LAST_CONFIRM_L4.getType(), targetMap.get(EsSumColumnEnum.LAST_CONFIRM_L4.getColumn()));
        }
        //获取skuCodes
        List<String> skuCodes = getSkuCodes(esAggregationDTO.getEsQuery().getCategoryCodeList());
        OtherTargetHandleUtil.handleEchartResult(otherTargetGeneralHandlerFacade.getEchartNecessaryOtherTargets(OtherTargetHandleUtil.getGeneralEchartQueryDTO(esAggregationDTO, OtherTargetsEnum.REQUIREMENT_PALN, skuCodes)), value);
        //设置预约在途采购量和未履约采购量
        int elementSize = weekDates.size();
        this.setEchartReservePurchaseQty(value, elementSize, weekDates.get(0).get("startTime"), weekDates.get(weekDates.size() - 1).get("endTime"), dates, esAggregationDTO.getEsQuery().getCategoryCodeList(), esAggregationDTO.getEsQuery().getWarehouseCodeList());
        eChartsDTO.setLabelData(this.getAllKeyLabels());
        eChartsDTO.setValue(value);
        eChartsDTO.setDateList(MyDateUtil.processCyclesDate(weekDates, "M.dd"));
        return eChartsDTO;
    }

    public ExcelExportDataDTO exportExcel(ExcelExportDTO excelExportDTO, Integer type, Long userId) {
        if (ObjectUtil.isEmpty(type)) {
            throw new RomeException(ResponseMsg.FAIL_2005.getCode(), "未传入导出类型");
        }
        List<SalesPlanSelectDTO> areaSalesPlanSelectDTOs = baseDataFacade.getSubAreaCode(excelExportDTO.getAreaCodeList());
        EsExportAggregationDTO esAggregationDTO = this.setExportSearchFields(excelExportDTO, excelExportDTO.getCategoryCodeList(), areaSalesPlanSelectDTOs);
        List<Map<String, Date>> weekDates = MyDateUtil.getWeekDates(excelExportDTO.getStartTime(), DataDisplayCycleEnum.WEEKLY_FOURTEEN.getValue());
        esAggregationDTO.getEsQuery().setStartDate(DateUtil.format(weekDates.get(0).get("startTime"), DatePattern.NORM_DATE_PATTERN));
        esAggregationDTO.getEsQuery().setEndDate(DateUtil.format(weekDates.get(weekDates.size() - 1).get("endTime"), DatePattern.NORM_DATE_PATTERN));
        //获取起始十四周起始日期字符串集合
        List<String> dateList = new ArrayList<>();
        List<Date> dates = new ArrayList<>();
        for (Map<String, Date> item : weekDates) {
            dateList.add(DateUtil.format(item.get("startTime"), DatePattern.NORM_DATE_PATTERN));
            dates.add(item.get("startTime"));
        }
        esAggregationDTO.setDateList(dateList);
        esAggregationDTO.setUnitType(excelExportDTO.getUnitType());
        List<List<Object>> exportDataList = new ArrayList<>();
        List<String> allTargetsDesc = this.getAllTargetsDesc();
        if (!ExcelExportTypeEnum.SEARCHED_DATA_EXPORT.getType().equals(type)) {
            esAggregationDTO.setPageNum(excelExportDTO.getPageNum());
            esAggregationDTO.setPageSize(excelExportDTO.getPageSize());
            //从缓存中拿导出数据
            List<EsReturnDTO> result = salesPlanEsLazyLoadingFacade.queryFromCache(this.getTransfer(esAggregationDTO, userId));
            if (CollectionUtils.isEmpty(result)) {
                throw new RomeException(ResponseMsg.FAIL_2005.getCode(), ResponseMsg.FAIL_2005.getMsg());
            }
            OtherTargetHandleUtil.handleResult(otherTargetGeneralHandlerFacade.getNecessaryOtherTargets(OtherTargetHandleUtil.getGeneralQueryDTO(this.getTransfer(esAggregationDTO, userId), result, OtherTargetsEnum.REQUIREMENT_PALN)), result);
            List<RequirementPlanInfoDTO> pageList = this.getExportPageList(result, excelExportDTO.getRowIndex());
            this.getExportDataList(exportDataList, pageList, allTargetsDesc);
        }
        if (ExcelExportTypeEnum.SEARCHED_DATA_EXPORT.getType().equals(type)) {
            EsScrollReturnDTO esScrollReturnDTO;
            do {
                esScrollReturnDTO = salesPlanEsFacade.exportByGroup(esAggregationDTO);
                if(!CollectionUtils.isEmpty(esScrollReturnDTO.getEsReturnDTOList())){
                    OtherTargetHandleUtil.handleResult(otherTargetGeneralHandlerFacade.getNecessaryOtherTargets(OtherTargetHandleUtil.getGeneralQueryDTO(this.getTransfer(esAggregationDTO, userId), esScrollReturnDTO.getEsReturnDTOList(), OtherTargetsEnum.REQUIREMENT_PALN)), esScrollReturnDTO.getEsReturnDTOList());
                }
                this.getExportDataList(exportDataList, this.getExportList(esScrollReturnDTO.getEsReturnDTOList()), allTargetsDesc);
                esAggregationDTO.setAfterKey(esScrollReturnDTO.getAfterKey());
            } while (esScrollReturnDTO.getAfterKey() != null);
            if (CollectionUtils.isEmpty(exportDataList)) {
                throw new RomeException(ResponseMsg.FAIL_2005.getCode(), ResponseMsg.FAIL_2005.getMsg());
            }
        }
        //写死静态合并单元格列:渠道，区域，品类，商品，单位
        List<List<String>> mainHeaders = this.getMainHeaders();
        int mergeCellsColumns = mainHeaders.size();
        //加入指标标题
        this.setTargetTitle(mainHeaders);
        //获取excel标题信息
        List<String> dateTitles = MyDateUtil.processCyclesDate(weekDates, "MM.dd");
        //加入日期标题
        getExcelDateTitle(mainHeaders, dateTitles);
        return ExcelExportUtil.getExcelExportData(mergeCellsColumns, exportDataList, mainHeaders, allTargetsDesc.size(), new GeneralCellWriteHandler());
    }

    private void getExportDataList(List<List<Object>> exportDataList, List<RequirementPlanInfoDTO> pageList, List<String> allTargetsDesc) {
        if (CollectionUtils.isEmpty(pageList)) {
            return;
        }
        List<Object> itemRow;
        List<BigDecimal> list1;
        List<BigDecimal> list2;
        List<BigDecimal> list3;
        List<BigDecimal> list4;
        List<BigDecimal> list5;
        List<BigDecimal> list6;
        List<BigDecimal> list7;
        List<BigDecimal> list8;
        List<BigDecimal> list9;
        List<BigDecimal> list10;
        List<BigDecimal> list11;
        List<BigDecimal> list12;
        List<BigDecimal> list13;
        List<BigDecimal> list14;
        List<BigDecimal> list15;
        List<BigDecimal> list16;
        List<BigDecimal> list17;
        List<BigDecimal> list18;
        for (RequirementPlanInfoDTO item : pageList) {
            list1 = item.getSalesPlanQty();
            list2 = item.getForecastPlanQty();
            list3 = item.getStockSafety();
            list4 = item.getTargetInventoryQty();
            list5 = item.getCoveredDays();
            list6 = item.getSupChainConfirmQty();
            list7 = item.getSalePlanConfirmationQty();
            list8 = item.getLastConfirmQty();
            list9 = item.getLastSalePlanConfirmQty();
            list10 = item.getPurchasePlanQty();
            list11 = item.getPurchaseOrderQty();
            list12 = item.getNoFulfilPurchaseQty();
            list13 = item.getConfirmedPurchaseOrderQty();
            list14 = item.getReservePurchaseQty();
            list15 = item.getActualQty();
            list16 = item.getActualStorageQty();
            list17 = item.getActualSalesQty();
            list18 = item.getRealTimeInventory();
            int actualIndex = 0;
            for (String target : allTargetsDesc) {
                itemRow = new ArrayList<>();
                itemRow.add(item.getChannel());
                itemRow.add(item.getPlanTypeName());
                itemRow.add(item.getWarehouseName() + "/" + item.getWarehouseCode());
                itemRow.add(item.getArea());
                itemRow.add(item.getCategory());
                itemRow.add(item.getSkuName() + "/" + item.getSkuCode());
                itemRow.add(target);
                //加入数据
                for (int j = 0; j < DataDisplayCycleEnum.WEEKLY_FOURTEEN.getValue(); j++) {
                    //获取指标集合，这里没有排序，默认使用枚举的顺序
                    switch (actualIndex) {
                        case 0:
                            itemRow.add(list1.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list1.get(j));
                            break;
                        case 1:
                            itemRow.add(list2.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list2.get(j));
                            break;
                        case 2:
                            itemRow.add(list3.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list3.get(j));
                            break;
                        case 3:
                            itemRow.add(list4.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list4.get(j));
                            break;
                        case 4:
                            itemRow.add(list5.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list5.get(j));
                            break;
                        case 5:
                            itemRow.add(list6.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list6.get(j));
                            break;
                        case 6:
                            itemRow.add(list7.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list7.get(j));
                            break;
                        case 7:
                            itemRow.add(list8.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list8.get(j));
                            break;
                        case 8:
                            itemRow.add(list9.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list9.get(j));
                            break;
                        case 9:
                            itemRow.add(list10.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list10.get(j));
                            break;
                        case 10:
                            itemRow.add(list11.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list11.get(j));
                            break;
                        case 11:
                            itemRow.add(list12.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list12.get(j));
                            break;
                        case 12:
                            itemRow.add(list13.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list13.get(j));
                            break;
                        case 13:
                            itemRow.add(list14.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list14.get(j));
                            break;
                        case 14:
                            itemRow.add(list15.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list15.get(j));
                            break;
                        case 15:
                            itemRow.add(list16.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list16.get(j));
                            break;
                        case 16:
                            itemRow.add(list17.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list17.get(j));
                            break;
                        case 17:
                            itemRow.add(list18.get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : list18.get(j));
                            break;
                        default:
                            break;
                    }
                }
                actualIndex++;
                exportDataList.add(itemRow);
            }
        }
    }

    private List<RequirementPlanInfoDTO> getExportList(List<EsReturnDTO> result) {
        if (CollectionUtils.isEmpty(result)) {
            return null;
        }
        List<RequirementPlanInfoDTO> pageList = new ArrayList<>();
        RequirementPlanInfoDTO requirementPlanInfoDTO;
        Map<String, List<BigDecimal>> targetmap;
        for (EsReturnDTO esReturnDTO : result) {
            requirementPlanInfoDTO = new RequirementPlanInfoDTO();
            requirementPlanInfoDTO.setChannel(esReturnDTO.getChannelName());
            requirementPlanInfoDTO.setArea(esReturnDTO.getArea());
            requirementPlanInfoDTO.setPlanTypeName(esReturnDTO.getPlanTypeName());
            requirementPlanInfoDTO.setCategory(esReturnDTO.getCategory());
            requirementPlanInfoDTO.setSkuName(esReturnDTO.getSkuName());
            requirementPlanInfoDTO.setSkuCode(esReturnDTO.getSkuCode());
            requirementPlanInfoDTO.setWarehouseName(esReturnDTO.getDeliverName());
            requirementPlanInfoDTO.setWarehouseCode(esReturnDTO.getDeliverId());
            //指标
            targetmap = esReturnDTO.getTargetMap();
            requirementPlanInfoDTO.setSupChainConfirmQty(targetmap.get(EsSumColumnEnum.REQUIRE_CONFIRM_QTY.getColumn()));
            requirementPlanInfoDTO.setLastConfirmQty(targetmap.get(EsSumColumnEnum.LAST_REQUIRE_CONFIRM_QTY.getColumn()));
            requirementPlanInfoDTO.setSalesPlanQty(targetmap.get(EsSumColumnEnum.SALES_PLAN_QTY.getColumn()));
            requirementPlanInfoDTO.setForecastPlanQty(targetmap.get(EsSumColumnEnum.FORECAST_PLAN_QTY.getColumn()));
            requirementPlanInfoDTO.setSalePlanConfirmationQty(targetmap.get(EsSumColumnEnum.CONFIRM_L4.getColumn()));
            requirementPlanInfoDTO.setLastSalePlanConfirmQty(targetmap.get(EsSumColumnEnum.LAST_CONFIRM_L4.getColumn()));
            //其它指标
            requirementPlanInfoDTO.setStockSafety(targetmap.get(TiSsEnum.STOCK_SAFETY.getName()));
            requirementPlanInfoDTO.setTargetInventoryQty(targetmap.get(TiSsEnum.TARGET_INVENTORY.getName()));
            requirementPlanInfoDTO.setCoveredDays(targetmap.get(TiSsEnum.COVERED_DAYS.getName()));
            requirementPlanInfoDTO.setPurchasePlanQty(targetmap.get(PurchaseOrderTargetEnum.PURCHASE_PLAN_QUANTITY.getName()));
            requirementPlanInfoDTO.setPurchaseOrderQty(targetmap.get(PurchaseOrderTargetEnum.PURCHASE_ORDER_QUANTITY.getName()));
            requirementPlanInfoDTO.setNoFulfilPurchaseQty(targetmap.get(PurchaseOrderTargetEnum.UNFULFILLED_PURCHASE_QUANTITY.getName()));
            requirementPlanInfoDTO.setConfirmedPurchaseOrderQty(targetmap.get(PurchaseOrderTargetEnum.CONFIRMED_PURCHASE_ORDERS.getName()));
            requirementPlanInfoDTO.setReservePurchaseQty(targetmap.get(PurchaseOrderTargetEnum.APPOINTMENT_PURCHASE_QUANTITY.getName()));
            requirementPlanInfoDTO.setActualQty(targetmap.get(OtherTargetsEnum.ACTUAL_QTY.getName()));
            requirementPlanInfoDTO.setActualStorageQty(targetmap.get(OtherTargetsEnum.ACTUAL_STORAGE_QTY.getName()));
            requirementPlanInfoDTO.setActualSalesQty(targetmap.get(OtherTargetsEnum.ACTUAL_SALES.getName()));
            requirementPlanInfoDTO.setRealTimeInventory(targetmap.get(OtherTargetsEnum.REAL_TIME_STOCK.getName()));
            pageList.add(requirementPlanInfoDTO);
        }
        return pageList;
    }

    private List<RequirementPlanInfoDTO> getExportPageList(List<EsReturnDTO> result, List<Integer> indexs) {
        boolean flag = false;
        if (indexs != null && indexs.size() > 0) {
            flag = true;
        }
        List<RequirementPlanInfoDTO> pageList = new ArrayList<>();
        RequirementPlanInfoDTO requirementPlanInfoDTO;
        Map<String, List<BigDecimal>> targetmap;
        int index = 0;
        for (EsReturnDTO esReturnDTO : result) {
            if (flag && !indexs.contains(index)) {
                index++;
                continue;
            }
            index++;
            requirementPlanInfoDTO = this.getRequirementPlanInfoDTO();
            requirementPlanInfoDTO.setChannel(esReturnDTO.getChannelName());
            requirementPlanInfoDTO.setArea(esReturnDTO.getArea());
            requirementPlanInfoDTO.setPlanTypeName(esReturnDTO.getPlanTypeName());
            requirementPlanInfoDTO.setCategory(esReturnDTO.getCategory());
            requirementPlanInfoDTO.setSkuName(esReturnDTO.getSkuName());
            requirementPlanInfoDTO.setSkuCode(esReturnDTO.getSkuCode());
            requirementPlanInfoDTO.setWarehouseName(esReturnDTO.getDeliverName());
            requirementPlanInfoDTO.setWarehouseCode(esReturnDTO.getDeliverId());
            //指标
            targetmap = esReturnDTO.getTargetMap();
            requirementPlanInfoDTO.setSupChainConfirmQty(targetmap.get(EsSumColumnEnum.REQUIRE_CONFIRM_QTY.getColumn()));
            requirementPlanInfoDTO.setLastConfirmQty(targetmap.get(EsSumColumnEnum.LAST_REQUIRE_CONFIRM_QTY.getColumn()));
            requirementPlanInfoDTO.setSalesPlanQty(targetmap.get(EsSumColumnEnum.SALES_PLAN_QTY.getColumn()));
            requirementPlanInfoDTO.setForecastPlanQty(targetmap.get(EsSumColumnEnum.FORECAST_PLAN_QTY.getColumn()));
            requirementPlanInfoDTO.setSalePlanConfirmationQty(targetmap.get(EsSumColumnEnum.CONFIRM_L4.getColumn()));
            requirementPlanInfoDTO.setLastSalePlanConfirmQty(targetmap.get(EsSumColumnEnum.LAST_CONFIRM_L4.getColumn()));
            //其它指标
            requirementPlanInfoDTO.setStockSafety(targetmap.get(TiSsEnum.STOCK_SAFETY.getName()));
            requirementPlanInfoDTO.setTargetInventoryQty(targetmap.get(TiSsEnum.TARGET_INVENTORY.getName()));
            requirementPlanInfoDTO.setCoveredDays(targetmap.get(TiSsEnum.COVERED_DAYS.getName()));
            requirementPlanInfoDTO.setPurchasePlanQty(targetmap.get(PurchaseOrderTargetEnum.PURCHASE_PLAN_QUANTITY.getName()));
            requirementPlanInfoDTO.setPurchaseOrderQty(targetmap.get(PurchaseOrderTargetEnum.PURCHASE_ORDER_QUANTITY.getName()));
            requirementPlanInfoDTO.setNoFulfilPurchaseQty(targetmap.get(PurchaseOrderTargetEnum.UNFULFILLED_PURCHASE_QUANTITY.getName()));
            requirementPlanInfoDTO.setConfirmedPurchaseOrderQty(targetmap.get(PurchaseOrderTargetEnum.CONFIRMED_PURCHASE_ORDERS.getName()));
            requirementPlanInfoDTO.setReservePurchaseQty(targetmap.get(PurchaseOrderTargetEnum.APPOINTMENT_PURCHASE_QUANTITY.getName()));
            requirementPlanInfoDTO.setActualQty(targetmap.get(OtherTargetsEnum.ACTUAL_QTY.getName()));
            requirementPlanInfoDTO.setActualStorageQty(targetmap.get(OtherTargetsEnum.ACTUAL_STORAGE_QTY.getName()));
            requirementPlanInfoDTO.setActualSalesQty(targetmap.get(OtherTargetsEnum.ACTUAL_SALES.getName()));
            requirementPlanInfoDTO.setRealTimeInventory(targetmap.get(OtherTargetsEnum.REAL_TIME_STOCK.getName()));
            pageList.add(requirementPlanInfoDTO);
        }
        return pageList;
    }

    private EsAggregationDTO getTransfer(EsExportAggregationDTO esAggregationDTO, Long userId) {
        EsAggregationDTO esAggregation = new EsAggregationDTO();
        esAggregation.setDateList(esAggregationDTO.getDateList());
        esAggregation.setEsQuery(esAggregationDTO.getEsQuery());
        esAggregation.setSumColumns(esAggregationDTO.getSumColumns());
        esAggregation.setGroupColumns(esAggregationDTO.getGroupColumns());
        esAggregation.setPageSize(esAggregationDTO.getPageSize());
        esAggregation.setPageNum(esAggregationDTO.getPageNum());
        esAggregation.setTableCode(TableCodeEnum.REQUIREMENT_PLAN.getCode());
        esAggregation.setUserId(userId);
        esAggregation.setUnitType(esAggregationDTO.getUnitType());
        return esAggregation;
    }

    private void setTargetTitle(List<List<String>> mainHeaders) {
        List<String> targetTitle = new ArrayList<>();
        targetTitle.add(ExcelExportTitleEnum.TARGET_TITLE.getTitle());
        mainHeaders.add(targetTitle);
    }

    private List<List<String>> getMainHeaders() {
        List<List<String>> mainHeaders = new ArrayList<>();
        //渠道
        AdvancedSearchUtil.setList(mainHeaders, ExcelExportTitleEnum.CHANNEL_TITLE.getTitle());
        //计划类型
        AdvancedSearchUtil.setList(mainHeaders, ExcelExportTitleEnum.PLAN_TITLE.getTitle());
        //仓库
        AdvancedSearchUtil.setList(mainHeaders, ExcelExportTitleEnum.WAREHOUSE.getTitle());
        //区域
        AdvancedSearchUtil.setList(mainHeaders, ExcelExportTitleEnum.AREA_TITLE.getTitle());
        //品类
        AdvancedSearchUtil.setList(mainHeaders, ExcelExportTitleEnum.CATEGORY_TITLE.getTitle());
        //商品
        AdvancedSearchUtil.setList(mainHeaders, ExcelExportTitleEnum.SKU_MAIN_TITLE.getTitle());
        return mainHeaders;
    }

    /**
     * 设置预约在途采购量
     *
     * @param pageResult
     * @param elementSize
     * @return void
     **/
    private void setReservePurchaseQty(List<RequirementPlanInfoDTO> pageResult, int elementSize, Date startTime, Date endTime, List<Date> dateList) {
        if (CollectionUtils.isEmpty(pageResult)) {
            return;
        }
        PlanPoQueryDTO planPoQueryDTO = this.getPlanPoQueryDTO(pageResult, startTime, endTime);
        // 预约在途采购量
//        List<PlanPoInfoDTO> appointments = purchaseFacade.listAppointmentQty(planPoQueryDTO);
//        //未履约采购量
//        List<PlanPoInfoDTO> noAgreement = purchaseFacade.listNoAgreementQty(planPoQueryDTO);
//        Map<String, BigDecimal> unitMap = this.getBaseSkuUnitRate(pageResult.stream().map(RequirementPlanInfoDTO::getSkuCode).distinct().collect(Collectors.toList()), SkuUnitTypeEnum.PURCHASE_UNIT.getUnitType());
        //根据仓库，skucode分组，获取每一组的 周起始时间——聚合值
        Map<String, Map<Date, BigDecimal>> result = new HashMap<>();
        Map<String, Map<Date, BigDecimal>> resultNoAgreement = new HashMap<>();
//        if (!CollectionUtils.isEmpty(appointments)) {
//            result = appointments.stream().peek(item -> item.setCreateTime(DateUtil.beginOfWeek(item.getCreateTime()))).collect(groupingBy(item -> item.getWarehouseCode() + item.getSkuCode(), Collectors.collectingAndThen(Collectors.toList(), values -> values.stream().collect(groupingBy(PlanPoInfoDTO::getCreateTime, Collectors.collectingAndThen(Collectors.toList(), subValues -> subValues.stream().map(PlanPoInfoDTO::getAppointmentQty).reduce(BigDecimal.ZERO, BigDecimal::add)))))));
//        }
//        if (!CollectionUtils.isEmpty(noAgreement)) {
//            resultNoAgreement = noAgreement.stream().peek(item -> item.setCreateTime(DateUtil.beginOfWeek(item.getCreateTime()))).collect(groupingBy(item -> item.getWarehouseCode() + item.getSkuCode(), Collectors.collectingAndThen(Collectors.toList(), values -> values.stream().collect(groupingBy(PlanPoInfoDTO::getCreateTime, Collectors.collectingAndThen(Collectors.toList(), subValues -> subValues.stream().map(PlanPoInfoDTO::getNoFulfilPurchaseQty).reduce(BigDecimal.ZERO, BigDecimal::add)))))));
//        }
        List<BigDecimal> blankList = this.getWeekBlankList(elementSize);
        Map<Date, BigDecimal> dateResult;
        Map<Date, BigDecimal> dateNoAgreement;
        List<BigDecimal> tmpList;
//        BigDecimal rate = null;
        BigDecimal tmpValue;
        for (RequirementPlanInfoDTO item : pageResult) {
//            rate = unitMap.get(item.getSkuCode());
//            if (rate == null) {
//                throw new RomeException(ResponseMsg.FAIL_6008.getCode(), "无法获取单位比例转换信息：" + "skuCode," + item.getSkuCode() + "; 单位类型" + SkuUnitTypeEnum.getNameByType(SkuUnitTypeEnum.PURCHASE_UNIT.getUnitType()));
//            }
            dateResult = result.get(item.getWarehouseCode() + item.getSkuCode());
            dateNoAgreement = resultNoAgreement.get(item.getWarehouseCode() + item.getSkuCode());
            if (dateResult != null) {
                tmpList = new ArrayList<>();
                for (Date date : dateList) {
                    tmpValue = dateResult.get(date);
                    if (tmpValue == null) {
                        tmpList.add(BigDecimal.ZERO);
                    } else {
                        tmpList.add(tmpValue);
                    }
                }
                item.setReservePurchaseQty(tmpList);
            } else {
                item.setReservePurchaseQty(blankList);
            }
            if (dateNoAgreement != null) {
                tmpList = new ArrayList<>();
                for (Date date : dateList) {
                    tmpValue = dateNoAgreement.get(date);
                    if (tmpValue == null) {
                        tmpList.add(BigDecimal.ZERO);
                    } else {
                        tmpList.add(tmpValue);
                    }
                }
                item.setNoFulfilPurchaseQty(tmpList);
            } else {
                item.setNoFulfilPurchaseQty(blankList);
            }
        }
    }

    private PlanPoQueryDTO getPlanPoQueryDTO(List<RequirementPlanInfoDTO> pageResult, Date startTime, Date endTime) {
        PlanPoQueryDTO planPoQueryDTO = new PlanPoQueryDTO();
        planPoQueryDTO.setStartTime(startTime);
        planPoQueryDTO.setEndTime(DateUtil.endOfDay(endTime));
        planPoQueryDTO.setSkuCodes(pageResult.stream().map(RequirementPlanInfoDTO::getSkuCode).distinct().collect(Collectors.toList()));
        planPoQueryDTO.setWarehouseCodes(pageResult.stream().map(RequirementPlanInfoDTO::getWarehouseCode).distinct().collect(Collectors.toList()));
        return planPoQueryDTO;
    }

    /**
     * 获取14周的空集合
     *
     * @param
     * @return {@link List<BigDecimal>}
     **/
    private List<BigDecimal> getWeekBlankList(int elementSize) {
        List<BigDecimal> blankList = new ArrayList<>(elementSize);
        for (int i = 0; i < elementSize; i++) {
            blankList.add(BigDecimal.ZERO);
        }
        return blankList;
    }

    private RequirementPlanInfoDTO getRequirementPlanInfoDTO() {
        RequirementPlanInfoDTO requirementPlanInfoDTO = new RequirementPlanInfoDTO();
        requirementPlanInfoDTO.setForecastPlanQtyLabel(RequirementPlanTargetEnum.FORECAST_PLAN_QTY.getDesc());
        requirementPlanInfoDTO.setSalesPlanQtyLabel(RequirementPlanTargetEnum.SALES_PLAN_QTY.getDesc());
        requirementPlanInfoDTO.setStockSafetyLabel(TiSsEnum.STOCK_SAFETY.getDesc());
        requirementPlanInfoDTO.setTargetInventoryQtyLabel(TiSsEnum.TARGET_INVENTORY.getDesc());
        requirementPlanInfoDTO.setCoveredDaysLabel(TiSsEnum.COVERED_DAYS.getDesc());
        requirementPlanInfoDTO.setSupChainConfirmQtyLabel(RequirementPlanTargetEnum.SUPPLY_CHAIN_CONFIRMATION_QTY.getDesc());
        requirementPlanInfoDTO.setSalePlanConfirmationQtyLabel(RequirementPlanTargetEnum.SALE_PLAN_CONFIRMATION_QTY.getDesc());
        requirementPlanInfoDTO.setLastConfirmQtyLabel(RequirementPlanTargetEnum.LAST_CONFIRM_QTY.getDesc());
        requirementPlanInfoDTO.setLastSalePlanConfirmQtyLabel(RequirementPlanTargetEnum.LAST_SALE_PLAN_CONFIRM_QTY.getDesc());
        requirementPlanInfoDTO.setPurchasePlanQtyLabel(PurchaseOrderTargetEnum.PURCHASE_PLAN_QUANTITY.getDesc());
        requirementPlanInfoDTO.setPurchaseOrderQtyLabel(PurchaseOrderTargetEnum.PURCHASE_ORDER_QUANTITY.getDesc());
        requirementPlanInfoDTO.setNoFulfilPurchaseQtyLabel(PurchaseOrderTargetEnum.UNFULFILLED_PURCHASE_QUANTITY.getDesc());
        requirementPlanInfoDTO.setConfirmedPurchaseOrderQtyLabel(PurchaseOrderTargetEnum.CONFIRMED_PURCHASE_ORDERS.getDesc());
        requirementPlanInfoDTO.setReservePurchaseQtyLabel(PurchaseOrderTargetEnum.APPOINTMENT_PURCHASE_QUANTITY.getDesc());
        requirementPlanInfoDTO.setActualQtyLabel(OtherTargetsEnum.ACTUAL_QTY.getDesc());
        requirementPlanInfoDTO.setActualStorageQtyLabel(OtherTargetsEnum.ACTUAL_STORAGE_QTY.getDesc());
        requirementPlanInfoDTO.setActualSalesQtyLabel(OtherTargetsEnum.ACTUAL_SALES.getDesc());
        requirementPlanInfoDTO.setRealTimeInventoryLabel(OtherTargetsEnum.REAL_TIME_STOCK.getDesc());
        return requirementPlanInfoDTO;
    }

    @Override
    public void updateConfirmQty(List<RequirementConfirmationDTO> requirementConfirmationDTOs, Long unitType) {
        requirementPlanFacade.updateConfirmQty(requirementConfirmationDTOs, unitType);
    }


    private List<String> getSkuCodes(List<SalesPlanSelectDTO> categoryCodeList) {
        if (!CollectionUtils.isEmpty(categoryCodeList)) {
            Integer level = categoryCodeList.get(0).getLevel();
            if (CommonConstants.CATEGORY_LEVEL_ONE.equals(level)) {
                //根据大品类获取中品类
                List<CategoryBaseInfoDTO> categoryBaseInfoDTOS = itemCoreFacade.categoryListByCategoryCodes(categoryCodeList.stream().map(SalesPlanSelectDTO::getCode).collect(Collectors.toList()));
                List<String> secCategoryCodeList = categoryBaseInfoDTOS.stream().map(CategoryBaseInfoDTO::getCategoryDTOList).
                        flatMap(Collection::stream).map(item -> item.getCode().toString()).collect(Collectors.toList());
                //根据中品类获取小品类
                List<CategoryBaseInfoDTO> secInfoDTOS = itemCoreFacade.listByCategoryCodes(secCategoryCodeList);
                List<Integer> terCategoryCodeList = secInfoDTOS.stream().map(CategoryBaseInfoDTO::getCategoryDTOList).
                        flatMap(Collection::stream).map(item -> Integer.valueOf(item.getId().toString())).collect(Collectors.toList());
                //根据小品类获取sku
                return this.pageQuerySkuCodes(terCategoryCodeList);
            }
            if (CommonConstants.CATEGORY_LEVEL_TWO.equals(level)) {
                //根据中品类获取小品类
                List<CategoryBaseInfoDTO> secInfoDTOS = itemCoreFacade.listByCategoryCodes(categoryCodeList.stream().map(SalesPlanSelectDTO::getCode).collect(Collectors.toList()));
                List<Integer> terCategoryCodeList = secInfoDTOS.stream().map(CategoryBaseInfoDTO::getCategoryDTOList).
                        flatMap(Collection::stream).map(item -> Integer.valueOf(item.getId().toString())).collect(Collectors.toList());
                //根据小品类获取sku
                return this.pageQuerySkuCodes(terCategoryCodeList);
            }
            if (CommonConstants.CATEGORY_LEVEL_THREE.equals(level)) {
                //根据小品类获取sku
                return this.pageQuerySkuCodes(categoryCodeList.stream().map(item -> Integer.valueOf(item.getId().toString())).collect(Collectors.toList()));
            }
            if (CommonConstants.CATEGORY_LEVEL_FOUR.equals(level)) {
                return categoryCodeList.stream().map(SalesPlanSelectDTO::getCode).collect(Collectors.toList());
            }
        }
        return null;
    }

    private List<String> pageQuerySkuCodes(List<Integer> terCategoryCodeList) {
        List<String> result = new ArrayList<>();
        List<SkuInfoDTO> list;
        int pageNum = 1;
        int size;
        if (!CollectionUtils.isEmpty(terCategoryCodeList)) {
            List<List<Integer>> lists = splitTo(terCategoryCodeList, 100);
            for (List<Integer> item : lists) {
                do {
                    //TODO 改成500条
                    list = itemCoreFacade.skuListByCategoryId(pageNum, item).getList();
                    size = list.size();
                    if (size > 0) {
                        result.addAll(list.stream().map(SkuInfoDTO::getSkuCode).collect(Collectors.toList()));
                    }
                    pageNum++;
                } while (size > 0);
            }
            return result;
        }
        return null;
    }

    /**
     * 设置预约在途采购量
     *
     * @param elementSize
     * @param warehouseCodeList
     * @return void
     **/
    private void setEchartReservePurchaseQty(Map<String, List<BigDecimal>> value, int elementSize, Date startTime, Date endTime, List<Date> dateList, List<SalesPlanSelectDTO> salesPlanSelectDTOS, List<String> warehouseCodeList) {
        if (CollectionUtils.isEmpty(value)) {
            return;
        }
        PlanPoQueryDTO planPoQueryDTO = this.getEchartPlanPoQueryDTO(salesPlanSelectDTOS, warehouseCodeList, startTime, endTime);
        // 预约在途采购量
//        List<PlanPoInfoDTO> appointments = purchaseFacade.listAppointmentQty(planPoQueryDTO);
//        //未履约采购量
//        List<PlanPoInfoDTO> noAgreement = purchaseFacade.listNoAgreementQty(planPoQueryDTO);
//        Map<String, BigDecimal> unitMap = this.getBaseSkuUnitRate(pageResult.stream().map(RequirementPlanInfoDTO::getSkuCode).distinct().collect(Collectors.toList()), SkuUnitTypeEnum.PURCHASE_UNIT.getUnitType());
        //根据仓库，skucode分组，获取每一组的 周起始时间——聚合值
        Map<Date, BigDecimal> result = new HashMap<>();
        Map<Date, BigDecimal> resultNoAgreement = new HashMap<>();
//        if (!CollectionUtils.isEmpty(appointments)) {
//            result = appointments.stream().peek(item -> item.setCreateTime(DateUtil.beginOfWeek(item.getCreateTime()))).collect(groupingBy(PlanPoInfoDTO::getCreateTime, Collectors.collectingAndThen(Collectors.toList(), subValues -> subValues.stream().map(PlanPoInfoDTO::getAppointmentQty).reduce(BigDecimal.ZERO, BigDecimal::add))));
//        }
//        if (!CollectionUtils.isEmpty(noAgreement)) {
//            resultNoAgreement = noAgreement.stream().peek(item -> item.setCreateTime(DateUtil.beginOfWeek(item.getCreateTime()))).collect(groupingBy(PlanPoInfoDTO::getCreateTime, Collectors.collectingAndThen(Collectors.toList(), subValues -> subValues.stream().map(PlanPoInfoDTO::getNoFulfilPurchaseQty).reduce(BigDecimal.ZERO, BigDecimal::add))));
//        }
        List<BigDecimal> blankList = this.getWeekBlankList(elementSize);
//        BigDecimal rate = null;
//            rate = unitMap.get(item.getSkuCode());
//            if (rate == null) {
//                throw new RomeException(ResponseMsg.FAIL_6008.getCode(), "无法获取单位比例转换信息：" + "skuCode," + item.getSkuCode() + "; 单位类型" + SkuUnitTypeEnum.getNameByType(SkuUnitTypeEnum.PURCHASE_UNIT.getUnitType()));
//            }
        List<BigDecimal> tmpList = new ArrayList<>();
        BigDecimal tmpValue;
        for (Date date : dateList) {
            tmpValue = result.get(date);
            if (tmpValue == null) {
                tmpList.add(BigDecimal.ZERO);
            } else {
                tmpList.add(tmpValue);
            }
        }
        value.put(RESERVE_PURCHASE_QTY.getType(), tmpList);
        tmpList = new ArrayList<>();
        for (Date date : dateList) {
            tmpValue = resultNoAgreement.get(date);
            if (tmpValue == null) {
                tmpList.add(BigDecimal.ZERO);
            } else {
                tmpList.add(tmpValue);
            }
        }
        value.put(NO_FULFIL_PURCHASE_QTY.getType(), tmpList);
    }

    private PlanPoQueryDTO getEchartPlanPoQueryDTO(List<SalesPlanSelectDTO> salesPlanSelectDTOS, List<String> warehouseCodeList, Date startTime, Date endTime) {
        PlanPoQueryDTO planPoQueryDTO = new PlanPoQueryDTO();
        planPoQueryDTO.setStartTime(startTime);
        planPoQueryDTO.setEndTime(DateUtil.endOfDay(endTime));
        if (!CollectionUtils.isEmpty(salesPlanSelectDTOS)) {
            Integer level = salesPlanSelectDTOS.get(0).getLevel();
            if (CommonConstants.CATEGORY_LEVEL_ONE.equals(level)) {
                //根据大品类获取中品类
                List<CategoryBaseInfoDTO> categoryBaseInfoDTOS = itemCoreFacade.categoryListByCategoryCodes(salesPlanSelectDTOS.stream().map(SalesPlanSelectDTO::getCode).collect(Collectors.toList()));
                List<String> secCategoryCodeList = categoryBaseInfoDTOS.stream().map(CategoryBaseInfoDTO::getCategoryDTOList).
                        flatMap(pList -> pList.stream()).map(item -> item.getCode().toString()).collect(Collectors.toList());
                //根据中品类获取小品类
                List<CategoryBaseInfoDTO> infoDTOS = itemCoreFacade.listByCategoryCodes(secCategoryCodeList);
                List<Long> terCategoryCodeList = infoDTOS.stream().map(CategoryBaseInfoDTO::getCategoryDTOList).
                        flatMap(pList -> pList.stream()).map(item -> item.getCode()).collect(Collectors.toList());
                planPoQueryDTO.setTerCategoryCodes(terCategoryCodeList);
            }
            if (CommonConstants.CATEGORY_LEVEL_TWO.equals(level)) {
                //根据中品类获取小品类
                List<CategoryBaseInfoDTO> categoryBaseInfoDTOS = itemCoreFacade.categoryListByCategoryCodes(salesPlanSelectDTOS.stream().map(SalesPlanSelectDTO::getCode).collect(Collectors.toList()));
                List<Long> terCategoryCodeList = categoryBaseInfoDTOS.stream().map(CategoryBaseInfoDTO::getCategoryDTOList).
                        flatMap(pList -> pList.stream()).map(item -> item.getCode()).collect(Collectors.toList());
                planPoQueryDTO.setTerCategoryCodes(terCategoryCodeList);
            }
            if (CommonConstants.CATEGORY_LEVEL_THREE.equals(level)) {
                planPoQueryDTO.setTerCategoryCodes(salesPlanSelectDTOS.stream().map(item -> Long.valueOf(item.getCode())).collect(Collectors.toList()));
            }
            if (CommonConstants.CATEGORY_LEVEL_FOUR.equals(level)) {
                planPoQueryDTO.setSkuCodes(salesPlanSelectDTOS.stream().map(SalesPlanSelectDTO::getCode).collect(Collectors.toList()));
            }
        }
        if (!CollectionUtils.isEmpty(warehouseCodeList)) {
            planPoQueryDTO.setWarehouseCodes(warehouseCodeList);
        }
        return planPoQueryDTO;
    }

    private List<EChartsLabelDTO> getAllKeyLabels() {
        List<RequirementPlanEnum> requirementPlanEnums = new ArrayList<>();
        requirementPlanEnums.add(RequirementPlanEnum.REQUIRE_CONFIRM_QTY);
        requirementPlanEnums.add(RequirementPlanEnum.LAST_REQUIRE_CONFIRM_QTY);
        requirementPlanEnums.add(RequirementPlanEnum.PLAN_SALES);
        requirementPlanEnums.add(RequirementPlanEnum.PREDICT_SALES);
        requirementPlanEnums.add(RequirementPlanEnum.CONFIRM_L4);
        requirementPlanEnums.add(RequirementPlanEnum.LAST_CONFIRM_L4);
        List<OtherTargetsEnum> otherTargetsEnums = new ArrayList<>();
        otherTargetsEnums.add(OtherTargetsEnum.ACTUAL_SALES);
        otherTargetsEnums.add(OtherTargetsEnum.REAL_TIME_STOCK);
        otherTargetsEnums.add(OtherTargetsEnum.ACTUAL_QTY);
        otherTargetsEnums.add(OtherTargetsEnum.ACTUAL_STORAGE_QTY);
        List<TiSsEnum> tiSsEnums = new ArrayList<>();
        tiSsEnums.add(TiSsEnum.TARGET_INVENTORY);
        tiSsEnums.add(TiSsEnum.STOCK_SAFETY);
        tiSsEnums.add(TiSsEnum.COVERED_DAYS);
        List<PurchaseOrderTargetEnum> purchaseOrderTargetEnums = new ArrayList<>();
        purchaseOrderTargetEnums.add(PurchaseOrderTargetEnum.CONFIRMED_PURCHASE_ORDERS);
        purchaseOrderTargetEnums.add(PurchaseOrderTargetEnum.APPOINTMENT_PURCHASE_QUANTITY);
        purchaseOrderTargetEnums.add(PurchaseOrderTargetEnum.PURCHASE_ORDER_QUANTITY);
        purchaseOrderTargetEnums.add(PurchaseOrderTargetEnum.PURCHASE_PLAN_QUANTITY);
        purchaseOrderTargetEnums.add(PurchaseOrderTargetEnum.UNFULFILLED_PURCHASE_QUANTITY);
        List<EChartsLabelDTO> list = new ArrayList<>();
        for (RequirementPlanEnum item : requirementPlanEnums) {
            EChartsLabelDTO eChartsDTOLabelDataDTO = new EChartsLabelDTO();
            eChartsDTOLabelDataDTO.setKey(item.getType());
            eChartsDTOLabelDataDTO.setLabel(item.getDesc());
            list.add(eChartsDTOLabelDataDTO);
        }
        for (OtherTargetsEnum item : otherTargetsEnums) {
            EChartsLabelDTO eChartsDTOLabelDataDTO = new EChartsLabelDTO();
            eChartsDTOLabelDataDTO.setKey(item.getName());
            eChartsDTOLabelDataDTO.setLabel(item.getDesc());
            list.add(eChartsDTOLabelDataDTO);
        }
        for (TiSsEnum item : tiSsEnums) {
            EChartsLabelDTO eChartsDTOLabelDataDTO = new EChartsLabelDTO();
            eChartsDTOLabelDataDTO.setKey(item.getName());
            eChartsDTOLabelDataDTO.setLabel(item.getDesc());
            list.add(eChartsDTOLabelDataDTO);
        }
        for (PurchaseOrderTargetEnum item : purchaseOrderTargetEnums) {
            EChartsLabelDTO eChartsDTOLabelDataDTO = new EChartsLabelDTO();
            eChartsDTOLabelDataDTO.setKey(item.getName());
            eChartsDTOLabelDataDTO.setLabel(item.getDesc());
            list.add(eChartsDTOLabelDataDTO);
        }
        return list;
    }

    private List<String> getAllTargetsDesc() {
        List<String> targets = new ArrayList<>();
        targets.add(RequirementPlanEnum.PLAN_SALES.getDesc());
        targets.add(RequirementPlanEnum.PREDICT_SALES.getDesc());
        targets.add(TiSsEnum.STOCK_SAFETY.getDesc());
        targets.add(TiSsEnum.TARGET_INVENTORY.getDesc());
        targets.add(TiSsEnum.COVERED_DAYS.getDesc());
        targets.add(RequirementPlanEnum.REQUIRE_CONFIRM_QTY.getDesc());
        targets.add(RequirementPlanEnum.CONFIRM_L4.getDesc());
        targets.add(RequirementPlanEnum.LAST_REQUIRE_CONFIRM_QTY.getDesc());
        targets.add(RequirementPlanEnum.LAST_CONFIRM_L4.getDesc());
        targets.add(PurchaseOrderTargetEnum.PURCHASE_PLAN_QUANTITY.getDesc());
        targets.add(PurchaseOrderTargetEnum.PURCHASE_ORDER_QUANTITY.getDesc());
        targets.add(PurchaseOrderTargetEnum.UNFULFILLED_PURCHASE_QUANTITY.getDesc());
        targets.add(PurchaseOrderTargetEnum.CONFIRMED_PURCHASE_ORDERS.getDesc());
        targets.add(PurchaseOrderTargetEnum.APPOINTMENT_PURCHASE_QUANTITY.getDesc());
        targets.add(OtherTargetsEnum.ACTUAL_QTY.getDesc());
        targets.add(OtherTargetsEnum.ACTUAL_STORAGE_QTY.getDesc());
        targets.add(OtherTargetsEnum.ACTUAL_SALES.getDesc());
        targets.add(OtherTargetsEnum.REAL_TIME_STOCK.getDesc());
        return targets;
    }

    private void setGeneralDateInfo(RequirementPlanDTO requirementPlanDTO, List<Map<String, Date>> weekDates) {
        List<Long> list = new ArrayList<>();
        List<Date> listDate = new ArrayList<>();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN);
        weekDates.forEach(item -> {
            list.add(LocalDateTime.parse(DateUtil.format(item.get("startTime"), DatePattern.NORM_DATETIME_PATTERN), dtf).toInstant(ZoneOffset.UTC).toEpochMilli());
            listDate.add(item.get("startTime"));
        });
        requirementPlanDTO.setThisDayOfLong(LocalDateTime.parse(DateUtil.format(DateUtil.beginOfWeek(new Date()), DatePattern.NORM_DATETIME_PATTERN), dtf).toInstant(ZoneOffset.UTC).toEpochMilli());
        requirementPlanDTO.setDateListOfLong(list);
        requirementPlanDTO.setDateList(listDate);
    }

    private EsAggregationDTO setEchartSearchFields(RequirementPlanDTO requirementPlanDTO, List<SalesPlanSelectDTO> categorySalesPlanSelectDTOs, List<SalesPlanSelectDTO> areaSalesPlanSelectDTOs) {
        EsAggregationDTO esAggregationDTO = new EsAggregationDTO();
        EsQueryDTO esQueryDTO = new EsQueryDTO();
        List<String> groupColumns = new ArrayList<>();
        //渠道
        if (!CollectionUtils.isEmpty(requirementPlanDTO.getFatherChannelCodeList())) {
            esQueryDTO.setChannelCodeList(requirementPlanDTO.getFatherChannelCodeList());
        }
        //计划类型
        if (!CollectionUtils.isEmpty(requirementPlanDTO.getPlanTypeList())) {
            esQueryDTO.setTypeList(requirementPlanDTO.getPlanTypeList());
        }
        //仓库
        if (CollectionUtils.isEmpty(requirementPlanDTO.getWarehouseCodeList())) {
            //获取默认的仓库集合
            esQueryDTO.setWarehouseCodeList(stockFacade.queryFactoryByRwType(16).stream().map(StoreDTO::getCode).collect(Collectors.toList()));
        } else {
            esQueryDTO.setWarehouseCodeList(requirementPlanDTO.getWarehouseCodeList());
        }
        //品类查询条件设置
        if (!CollectionUtils.isEmpty(categorySalesPlanSelectDTOs)) {
            esQueryDTO.setCategoryCodeList(categorySalesPlanSelectDTOs);
        }
        //地域查询条件设置
        if (!CollectionUtils.isEmpty(areaSalesPlanSelectDTOs)) {
            esQueryDTO.setQueryAreaCodeList(areaSalesPlanSelectDTOs);
        }
        List<String> sumColumns = new ArrayList<>();
        sumColumns.add(EsSumColumnEnum.SALES_PLAN_AMOUNT.getColumn());
        sumColumns.add(EsSumColumnEnum.FORECAST_PLAN_AMOUNT.getColumn());
        sumColumns.add(EsSumColumnEnum.REQUIRE_CONFIRM_QTY.getColumn());
        sumColumns.add(EsSumColumnEnum.LAST_REQUIRE_CONFIRM_QTY.getColumn());
        sumColumns.add(EsSumColumnEnum.SALES_PLAN_QTY.getColumn());
        sumColumns.add(EsSumColumnEnum.FORECAST_PLAN_QTY.getColumn());
        sumColumns.add(EsSumColumnEnum.CONFIRM_L4.getColumn());
        sumColumns.add(EsSumColumnEnum.LAST_CONFIRM_L4.getColumn());
        sumColumns.add(EsSumColumnEnum.SS.getColumn());
        esAggregationDTO.setGroupColumns(groupColumns);
        esAggregationDTO.setSumColumns(sumColumns);
        esAggregationDTO.setEsQuery(esQueryDTO);
        return esAggregationDTO;
    }

    private EsExportAggregationDTO setExportSearchFields(ExcelExportDTO excelExportDTO, List<SalesPlanSelectDTO> categoryCodeList, List<SalesPlanSelectDTO> areaSalesPlanSelectDTOs) {
        EsExportAggregationDTO esAggregationDTO = new EsExportAggregationDTO();
        esAggregationDTO.setUnitType(excelExportDTO.getUnitType());
        EsQueryDTO esQueryDTO = new EsQueryDTO();
        List<String> groupColumns = new ArrayList<>();
        //渠道
        if (!excelExportDTO.getEdit()) {
            groupColumns.add(EsConmulEnum.CHANNEL_KEYWORD.getFName());
            if (!CollectionUtils.isEmpty(excelExportDTO.getFatherChannelCodeList())) {
                esQueryDTO.setChannelCodeList(excelExportDTO.getFatherChannelCodeList());
            }
        }
        //计划类型
        if (!excelExportDTO.getEdit()) {
            groupColumns.add(EsConmulEnum.PLAN_TYPE.getFName());
            if (!CollectionUtils.isEmpty(excelExportDTO.getTypeList())) {
                esQueryDTO.setTypeList(excelExportDTO.getTypeList());
            }
        }
        groupColumns.add(EsConmulEnum.WAREHOUSE_KEYWORD.getFName());
        groupColumns.add(EsConmulEnum.SKU_KEYWORD.getFName());
        //仓库
        if (CollectionUtils.isEmpty(excelExportDTO.getWarehouseCodeList())) {
            //获取默认的仓库集合
            esQueryDTO.setWarehouseCodeList(stockFacade.queryFactoryByRwType(16).stream().map(StoreDTO::getCode).collect(Collectors.toList()));
        } else {
            esQueryDTO.setWarehouseCodeList(excelExportDTO.getWarehouseCodeList());
        }
        //品类查询条件设置
        if (!CollectionUtils.isEmpty(categoryCodeList)) {
            esQueryDTO.setCategoryCodeList(categoryCodeList);
        }
        //地域查询条件设置
        if (!excelExportDTO.getEdit()) {
            if (!CollectionUtils.isEmpty(areaSalesPlanSelectDTOs)) {
                esQueryDTO.setQueryAreaCodeList(excelExportDTO.getAreaCodeList());
                Integer level = areaSalesPlanSelectDTOs.get(0).getLevel();
                if (CommonConstants.AREA_LEVEL_ONE.equals(level)) {
                    groupColumns.add(EsConmulEnum.PROVINCE_CODE_KEYWORD.getFName());
                }
                if (CommonConstants.AREA_LEVEL_TWO.equals(level)) {
                    groupColumns.add(EsConmulEnum.CITY_CODE_KEYWORD.getFName());
                }
                if (CommonConstants.AREA_LEVEL_THREE.equals(level)) {
                    groupColumns.add(EsConmulEnum.COUNTY_CODE_KEYWORD.getFName());
                }
                if (CommonConstants.AREA_LEVEL_FOUR.equals(level)) {
                    groupColumns.add(EsConmulEnum.STORE_KEYWORD.getFName());
                }
            } else {
                //默认按照省份分组
                groupColumns.add(EsConmulEnum.PROVINCE_CODE_KEYWORD.getFName());
            }
        }
        List<String> sumColumns = new ArrayList<>();
//        sumColumns.add(EsSumColumnEnum.SALES_PLAN_AMOUNT.getColumn());
//        sumColumns.add(EsSumColumnEnum.FORECAST_PLAN_AMOUNT.getColumn());
        sumColumns.add(EsSumColumnEnum.REQUIRE_CONFIRM_QTY.getColumn());
        sumColumns.add(EsSumColumnEnum.LAST_REQUIRE_CONFIRM_QTY.getColumn());
        sumColumns.add(EsSumColumnEnum.SALES_PLAN_QTY.getColumn());
        sumColumns.add(EsSumColumnEnum.FORECAST_PLAN_QTY.getColumn());
        sumColumns.add(EsSumColumnEnum.CONFIRM_L4.getColumn());
        sumColumns.add(EsSumColumnEnum.LAST_CONFIRM_L4.getColumn());
        sumColumns.add(EsSumColumnEnum.SS.getColumn());
        sumColumns.add(EsSumColumnEnum.SALE_INVENTORY.getColumn());
        esAggregationDTO.setGroupColumns(groupColumns);
        esAggregationDTO.setSumColumns(sumColumns);
        esAggregationDTO.setEsQuery(esQueryDTO);
        esAggregationDTO.setAfterKey("");
        return esAggregationDTO;
    }

    private EsAggregationDTO setSearchFields(RequirementPlanDTO requirementPlanDTO, List<SalesPlanSelectDTO> categoryCodeList, List<SalesPlanSelectDTO> areaSalesPlanSelectDTOs) {
        EsAggregationDTO esAggregationDTO = new EsAggregationDTO();
        EsQueryDTO esQueryDTO = new EsQueryDTO();
        List<String> groupColumns = new ArrayList<>();
        //渠道
        if (!requirementPlanDTO.getEdit()) {
            groupColumns.add(EsConmulEnum.CHANNEL_KEYWORD.getFName());
            if (!CollectionUtils.isEmpty(requirementPlanDTO.getFatherChannelCodeList())) {
                esQueryDTO.setChannelCodeList(requirementPlanDTO.getFatherChannelCodeList());
            }
        }
        //计划类型
        if (!requirementPlanDTO.getEdit()) {
            groupColumns.add(EsConmulEnum.PLAN_TYPE.getFName());
            if (!CollectionUtils.isEmpty(requirementPlanDTO.getPlanTypeList())) {
                esQueryDTO.setTypeList(requirementPlanDTO.getPlanTypeList());
            }
        }
        groupColumns.add(EsConmulEnum.WAREHOUSE_KEYWORD.getFName());
        groupColumns.add(EsConmulEnum.SKU_KEYWORD.getFName());
        //仓库
        if (CollectionUtils.isEmpty(requirementPlanDTO.getWarehouseCodeList())) {
            //获取默认的仓库集合
            esQueryDTO.setWarehouseCodeList(stockFacade.queryFactoryByRwType(16).stream().map(StoreDTO::getCode).collect(Collectors.toList()));
        } else {
            esQueryDTO.setWarehouseCodeList(requirementPlanDTO.getWarehouseCodeList());
        }
        //品类查询条件设置
        if (!CollectionUtils.isEmpty(categoryCodeList)) {
            esQueryDTO.setCategoryCodeList(categoryCodeList);
        }
        //地域查询条件设置
        if (!requirementPlanDTO.getEdit()) {
            if (!CollectionUtils.isEmpty(areaSalesPlanSelectDTOs)) {
                esQueryDTO.setQueryAreaCodeList(requirementPlanDTO.getAreaCodeList());
                Integer level = areaSalesPlanSelectDTOs.get(0).getLevel();
                if (CommonConstants.AREA_LEVEL_ONE.equals(level)) {
                    requirementPlanDTO.setExistPro(true);
                    groupColumns.add(EsConmulEnum.PROVINCE_CODE_KEYWORD.getFName());
                }
                if (CommonConstants.AREA_LEVEL_TWO.equals(level)) {
                    requirementPlanDTO.setExistCity(true);
                    groupColumns.add(EsConmulEnum.CITY_CODE_KEYWORD.getFName());
                }
                if (CommonConstants.AREA_LEVEL_THREE.equals(level)) {
                    requirementPlanDTO.setExistCount(true);
                    groupColumns.add(EsConmulEnum.COUNTY_CODE_KEYWORD.getFName());
                }
                if (CommonConstants.AREA_LEVEL_FOUR.equals(level)) {
                    requirementPlanDTO.setExistStore(true);
                    groupColumns.add(EsConmulEnum.STORE_KEYWORD.getFName());
                }
            } else {
                //默认按照省份分组
                groupColumns.add(EsConmulEnum.PROVINCE_CODE_KEYWORD.getFName());
            }
        }
        List<String> sumColumns = new ArrayList<>();
//        sumColumns.add(EsSumColumnEnum.SALES_PLAN_AMOUNT.getColumn());
//        sumColumns.add(EsSumColumnEnum.FORECAST_PLAN_AMOUNT.getColumn());
        sumColumns.add(EsSumColumnEnum.REQUIRE_CONFIRM_QTY.getColumn());
        sumColumns.add(EsSumColumnEnum.LAST_REQUIRE_CONFIRM_QTY.getColumn());
        sumColumns.add(EsSumColumnEnum.SALES_PLAN_QTY.getColumn());
        sumColumns.add(EsSumColumnEnum.FORECAST_PLAN_QTY.getColumn());
        sumColumns.add(EsSumColumnEnum.CONFIRM_L4.getColumn());
        sumColumns.add(EsSumColumnEnum.LAST_CONFIRM_L4.getColumn());
        sumColumns.add(EsSumColumnEnum.SS.getColumn());
        esAggregationDTO.setGroupColumns(groupColumns);
        esAggregationDTO.setSumColumns(sumColumns);
        esAggregationDTO.setEsQuery(esQueryDTO);
        return esAggregationDTO;
    }

    @Override
    public Map<String, String> listAllPlanTypes() {
        return SalesOtherTypeEnum.getAllPlans();
    }

    /**
     * 导入
     *
     * @param file
     * @return void
     **/
    @Override
    public Boolean importExcel(MultipartFile file, Long unitType) {
        RequirementDataListener requirementDataListener = new RequirementDataListener();
        try {
            EasyExcel.read(file.getInputStream(), RequirementDTO.class, requirementDataListener).sheet().headRowNumber(1).doRead();
        } catch (IOException e) {
            throw new RomeException(ResponseMsg.EXCEPTION.getCode(), "IO异常");
        } catch (ExcelAnalysisException e) {
            throw new RomeException(ResponseMsg.EXCEPTION.getCode(), e.getMessage());
        } catch (Exception e) {
            throw new RomeException(ResponseMsg.EXCEPTION.getCode(), "未知异常");
        }
        List<RequirementConfirmationDTO> paramDataList = requirementDataListener.getRequirementConfirmationDTOs();
        paramDataList = paramDataList.stream()
                .filter(e -> e.getSupplyChainConfirmationQty().compareTo(BigDecimal.ZERO) != 0).collect(Collectors.toList());
        OperationLogRecordDTO logRecord = getLogRecord("需求计划导入", UserContext.getApplicationUser());
        logRecord = logRecordFacade.insertOperationLog(logRecord);
        requirementPlanServiceImpl.updateConfirm(paramDataList, unitType, logRecord);
        return Boolean.TRUE;
    }

    @Override
    @Async
    public void updateConfirm(List<RequirementConfirmationDTO> paramList, Long unitType, OperationLogRecordDTO logRecord) {
        long opTime = 0;
        try {
            long start = System.currentTimeMillis();
            requirementPlanFacade.updateConfirmQty(paramList, unitType);
            long end = System.currentTimeMillis();
            opTime = (end - start) * 1000;
            logRecord.setOpStatus(OperationStatusEnum.SUCCESS.getType());
            logRecord.setFailReason("导入成功，请刷新页面查看");
            logRecord.setOpEndTime(new Date());
            logRecord.setOpTime(opTime + "s");
            logRecordFacade.updateOperationLog(logRecord);
        } catch (Exception e) {
            logRecord.setOpTime(opTime + "s");
            logRecord.setOpStatus(OperationStatusEnum.FAIL.getType());
            logRecord.setOpEndTime(new Date());
            logRecord.setFailReason("更新操作失败");
            logRecordFacade.updateOperationLog(logRecord);
        }
    }

    private OperationLogRecordDTO getLogRecord(String opContent, ApplicationUserInfoDTO applicationUser) {
        OperationLogRecordDTO logRecord = new OperationLogRecordDTO();
        logRecord.setOpContent(opContent);
        logRecord.setOpStatus(OperationStatusEnum.PROCESSING.getType());
        logRecord.setOpType(OperationTypeEnum.IMPORT.getType());
        logRecord.setOpSource(OperationSourceEnum.TWO_PLAN.getTableType());
        logRecord.setStartTime(new Date());
        logRecord.setCreator(UserContext.getUserId());
        logRecord.setCreatorName(applicationUser == null ? "admin" : applicationUser.getUsername());
        return logRecord;
    }

    @Override
    public OperationLogRecordDTO saveOperatorLog(ExcelExportDTO excelExportDTO, Integer type) {
        OperationLogRecordDTO operationDto = new OperationLogRecordDTO();
        Long userId = UserContext.getUserId();
        operationDto.setOpContent(OperationSourceEnum.TWO_PLAN.getDesc() + "-" + type);
        operationDto.setOpType(OperationTypeEnum.EXPORT.getType());
        operationDto.setOpStatus(OperationStatusEnum.PROCESSING.getType());
        operationDto.setOpSource(OperationSourceEnum.TWO_PLAN.getTableType());
        operationDto.setCreateTime(new Date());
        operationDto.setUpdateTime(new Date());
        operationDto.setCreator(userId);
        operationDto.setCreatorName(userId == 0 ? "system" : UserContext.getApplicationUser().getUsername());
        return logRecordFacade.insertOperationLog(operationDto);
    }

    @Async
    @Override
    public void createExportFile(OperationLogRecordDTO operationDto, ExcelExportDTO excelExportDTO, Integer type, Long userId) {
        String ext = "";
        Integer opStatus = OperationStatusEnum.SUCCESS.getType();
        try {
            ExcelExportDataDTO excelExportDataDTO = this.exportExcel(excelExportDTO, type, userId);
            // 指定文件夹
            String folderName = OperationSourceEnum.TWO_PLAN.getTableType().toString();
            //获取文件名
            String fileName = ExcelExportUtil.getFileName(OperationSourceEnum.TWO_PLAN.getDesc(), userId, type);
            //写文件并返回路径
            ext = ExcelExportUtil.exportExcel(excelExportDataDTO, folderName, filePath, fileName);
        } catch (RomeException e) {
            opStatus = OperationStatusEnum.FAIL.getType();
            operationDto.setFailReason(e.getMessage());
            log.error("需求计划导出失败", e);
        } catch (Exception e) {
            log.error("需求计划导出失败", e);
            opStatus = OperationStatusEnum.FAIL.getType();
            operationDto.setFailReason("导出失败");
        }
        operationDto.setExt(ext);
        operationDto.setOpStatus(opStatus);
        operationDto.setOpEndTime(new Date());
        logRecordFacade.updateOperationLog(operationDto);
    }
}
